﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using InspectionMAC.Forms;
using InspectionMAC.Function;
using InspectionMAC.SystemThread;
using InspectionMAC.Config;
using MvCameraControl;
using MvCamCtrl.NET;
using System.Runtime.InteropServices;
using csLTDMC;
using InspectionMAC.Algorithm;
using System.IO;
using System.Collections.Concurrent;
using System.Threading;
using LitJson;
using System.Diagnostics;
using System.Reflection;

namespace InspectionMAC.Forms
{
    public partial class MacTestForm : Form
    {
        public static MacTestForm macTestForm;
        public static Param_Form2 param_Form2;
        public static AlgorithmForm algorithm_Form;
        public static ProductSettingForm product_Form;
        public static PointSetForm pointset_Form;
        public static AlarmForm alarm_Form;
        public PictureBox[] pictureBoxes = new PictureBox[3];
        public bool isHaveCard = false;

        // 添加保存日志所需的新字段
        private System.Windows.Forms.Timer saveTimer;
        private int lastSaveLength = 0;
        private DateTime lastSaveDate = DateTime.MinValue;
        private string currentLogFilePath = "";
        private bool isClosing = false;

        //private string configFilePath = "axis_parameters.json";
        //public AxisParameters axisParameters = new AxisParameters();

        private System.Drawing.Point[] PicStartPos = new System.Drawing.Point[3];
        private System.Drawing.Size[] PicSize = new System.Drawing.Size[3];
        private int ZoomStep = 40;

        public string engineType;

        private string mergedConfigFilePath = "app_config.json";
        public AppConfig appConfig = new AppConfig();
        //public bool isMainCameraPbWheel;
        public MacTestForm()
        {
            InitializeComponent();
        }
        // 在程序初始化时启动清理任务
        private static System.Threading.Timer _dropDetectionCleanupTimer;

        public static void InitializeDropDetection()
        {
            _dropDetectionCleanupTimer = new System.Threading.Timer(_ =>
            {
                MaterialTracker.CleanupExpiredTransitions();
            }, null, 60000, 60000);
        }
        private void MacTestForm_Load(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Maximized;
            macTestForm = this;

            LoadMergedConfig();
            BtnSet_Click(null, EventArgs.Empty);
            AddPointThread01.MIN_TRIGGER_INTERVAL_MS = Pass_ms;
            AddPointThread02.MIN_TRIGGER_INTERVAL_MS = Pass_ms;
            NGKickManager.MIN_KICK_INTERVAL_MS = Pass_ms;
            //this.AutoScroll = true;//自动滚动
            //AutoScrollMinSize = new Size(1080, 1920);//设置自动滚动的最小大小
            //AutoScrollMargin = new Size(10, 10);//设置自动滚动边距的大小
            //Bitmap bitmap = new Bitmap(@"Test\First.bmp");
            cameraPb_01.SizeMode = PictureBoxSizeMode.Zoom;
            //cameraPb_01.Image = bitmap;
            cameraPb_02.SizeMode = PictureBoxSizeMode.Zoom;
            //cameraPb_02.Image = bitmap;
            cameraPb_03.SizeMode = PictureBoxSizeMode.Zoom;
            //cameraPb_03.Image = bitmap;



            pictureBoxes[0] = cameraPb_01;
            pictureBoxes[1] = cameraPb_02;
            pictureBoxes[2] = cameraPb_03;
            cameraPb_01.SizeMode = PictureBoxSizeMode.Zoom;
            cameraPb_02.SizeMode = PictureBoxSizeMode.Zoom;
            cameraPb_03.SizeMode = PictureBoxSizeMode.Zoom;

            PicStartPos[0] = cameraPb_01.Location;
            PicSize[0] = cameraPb_01.Size;

            PicStartPos[1] = cameraPb_02.Location;
            PicSize[1] = cameraPb_02.Size;

            PicStartPos[2] = cameraPb_03.Location;
            PicSize[2] = cameraPb_03.Size;

            // 为所有三个 PictureBox 注册鼠标滚轮事件
            this.cameraPb_01.MouseWheel += new MouseEventHandler(this.CameraPb_MouseWheel);
            this.cameraPb_02.MouseWheel += new MouseEventHandler(this.CameraPb_MouseWheel);
            this.cameraPb_03.MouseWheel += new MouseEventHandler(this.CameraPb_MouseWheel);
            InitializeDisplayTimer();
            InitializeDropDetection();
            runStateTimer = new System.Windows.Forms.Timer { Interval = 20 };
            runStateTimer.Tick += runStateTimer_Tick;
            runStateTimer.Start();
            Initial_Card.DMC300_InitialClass();//检测板卡状态
            if (!isHaveCard)
                return;
            LTDMC.dmc_write_sevon_pin(DMC300_Info.usCardId[0], 0, 0);
            LTDMC.dmc_write_sevon_pin(DMC300_Info.usCardId[0], 1, 0);
            LTDMC.dmc_write_sevon_pin(DMC300_Info.usCardId[0], 2, 0);
            LTDMC.dmc_write_sevon_pin(DMC300_Info.usCardId[0], 3, 0);
            LTDMC.dmc_set_encoder_dir(0, 0, 1);
            LTDMC.dmc_set_encoder_dir(0, 1, 0);
            LTDMC.dmc_set_encoder_dir(0, 2, 1);//反转计数
            LTDMC.dmc_set_alm_mode(0, 0, 1, 1, 0);
            LTDMC.dmc_set_alm_mode(0, 1, 1, 1, 0);
            LTDMC.dmc_set_alm_mode(0, 2, 1, 1, 0);
            LTDMC.dmc_set_alm_mode(0, 3, 1, 1, 0);//伺服设为高
            ///----一開始就啟動一維位置比較功能，並且先強制清除裡面的比較位置值-----------
            LTDMC.dmc_compare_set_config(0, 0, 1, 1);
            LTDMC.dmc_compare_clear_points(0, 0);
            LTDMC.dmc_compare_set_config(0, 1, 1, 1);
            LTDMC.dmc_compare_clear_points(0, 1);
            LTDMC.dmc_compare_set_config(0, 2, 1, 1);
            LTDMC.dmc_compare_clear_points(0, 2);
            ///---------------------------------------------------------------------------


            DIO_Thread.DIO_State();  //DIO线程启动




            //OpenContinuesMode();
            //OpenTriggerMode(isSoftTrigger);
            //StartGrab();

            //CameraTriggerService.CameraImgGet_Thread();
            TestDioThread.TestDio_Thread();

            AddPointThread01.AddPoint_Thread();
            AddPointThread02.AddPoint_Thread();
            BuilderManager.Initialize();
            CameraReceiveThread_01.CameraInitialize();
            CameraReceiveThread_02.CameraInitialize();
            CameraReceiveThread_03.CameraInitialize();
            GetCameraImgThread01.CameraImgGet_Thread();
            GetCameraImgThread02.CameraImgGet_Thread();
            GetCameraImgThread03.CameraImgGet_Thread();
            NGKickManager.Initialize();
            DataStorageToExcelThread.Initialize();
            AlgorithmThread.AlgorithmThreadInit();
            AlgorithmThread.iAlgorithm_Step = 10;
            InitializeSaveTimer();//日志存储

            InitializeIdleDetectionTimer();
            CameraContinuesThread01.CameraContinues_Thread();
            CameraContinuesThread02.CameraContinues_Thread();
            CameraContinuesThread03.CameraContinues_Thread();



            changeSpeedTb.Text = appConfig.AxisParameters.Axes[0].RunSpeed;
            changeTimeTb.Text = appConfig.AxisParameters.Axes[0].UpTime;

            changeSpeedTb04.Text = appConfig.AxisParameters.Axes[1].RunSpeed;
            changeTimeTb04.Text = appConfig.AxisParameters.Axes[1].UpTime;

            if (appConfig.AppSettings.IsMarginCheck)
            {
                MarginThread.RecordLocation_Thread();
                button7.Text = "关闭缺料感应";
            }
            else
            {
                button7.Text = "开启缺料感应";
            }
        }
        private void LoadMergedConfig()
        {
            try
            {
                if (File.Exists(mergedConfigFilePath))
                {
                    string json = File.ReadAllText(mergedConfigFilePath);
                    appConfig = JsonMapper.ToObject<AppConfig>(json);

                    if (appConfig == null)
                    {
                        CreateDefaultConfig();
                    }
                    else
                    {
                        if (appConfig.AxisParameters == null)
                            appConfig.AxisParameters = new AxisParameters();

                        if (appConfig.AxisParameters.Axes == null)
                            appConfig.AxisParameters.Axes = new List<AxisConfig>();

                        if (appConfig.AppSettings == null)
                            appConfig.AppSettings = new AppSettings();

                        if (appConfig.AppSettings.Cameras == null)
                            appConfig.AppSettings.Cameras = new CameraConfig[3];


                        // 如果轴数量不足，创建默认配置
                        if (appConfig.AxisParameters.Axes.Count < 2)
                        {
                            CreateDefaultConfig();
                        }

                        if (string.IsNullOrEmpty(appConfig.ProductConfigFileName))
                        {
                            appConfig.ProductConfigFileName = "ProductSettings.json";
                            SettingsFilePath = appConfig.ProductConfigFileName;
                        }
                    }

                    ApplyConfigToUI();
                    AddLog("配置文件加载成功");
                }
                else
                {
                    CreateDefaultConfig();
                    SaveMergedConfig();
                    AddLog("创建默认配置文件");
                }
            }
            catch (Exception ex)
            {
                AddLog($"加载配置失败: {ex.Message}");
                CreateDefaultConfig();
                SaveMergedConfig();
            }
        }

        private void CreateDefaultConfig()
        {
            appConfig = new AppConfig
            {
                AxisParameters = new AxisParameters(),
                AppSettings = new AppSettings(),
                ProductConfigFileName = "ProductSettings.json"  // 默认使用文档3的文件名
            };

            // 初始化2个轴的配置
            var axisConfig1 = new AxisConfig
            {
                StartSpeed = "1000",
                RunSpeed = "50000",
                UpTime = "0.1",
                DownTime = "0.1",
                StopSpeed = "2000",
                S_Time = "0.1",
                MotorCircle = "10000",
                IsForward = true,
                ChangeSpeed = "10000",
                ChangeTime = "0.2"
            };

            var axisConfig2 = new AxisConfig
            {
                StartSpeed = "100",
                RunSpeed = "10000",
                UpTime = "0.5",
                DownTime = "0.5",
                StopSpeed = "100",
                S_Time = "0.2",
                MotorCircle = "10000",
                IsForward = true,
                ChangeSpeed = "50000",
                ChangeTime = "0.5"
            };

            appConfig.AxisParameters.Axes.Add(axisConfig1);
            appConfig.AxisParameters.Axes.Add(axisConfig2);

            // 初始化相机配置
            appConfig.AppSettings.Cameras = new CameraConfig[3];
            appConfig.AppSettings.Cameras[0] = new CameraConfig { CameraId = "DA5335306" };
            appConfig.AppSettings.Cameras[1] = new CameraConfig { CameraId = "DA5335361" };
            appConfig.AppSettings.Cameras[2] = new CameraConfig { CameraId = "DA5335322" };

            appConfig.AppSettings.KickMs = 100;
            appConfig.AppSettings.PassMs = 150;
            appConfig.AppSettings.Sensor1To2Distance = 144726;
            appConfig.AppSettings.AllowedPositionError = 5000;
        }

        private void ApplyConfigToUI()
        {
            // 应用轴参数
            if (appConfig.AxisParameters.Axes.Count >= 2)
            {
                changeSpeedTb.Text = appConfig.AxisParameters.Axes[0].RunSpeed;
                changeTimeTb.Text = appConfig.AxisParameters.Axes[0].UpTime;

                changeSpeedTb04.Text = appConfig.AxisParameters.Axes[1].RunSpeed;
                changeTimeTb04.Text = appConfig.AxisParameters.Axes[1].UpTime;
            }

            // 应用时间参数
            KickMsTb.Text = appConfig.AppSettings.KickMs.ToString();
            textBox1.Text = appConfig.AppSettings.PassMs.ToString();
            textBox3.Text = appConfig.AppSettings.AllowedPositionError.ToString();
            MaterialTracker.SENSOR1_TO_SENSOR2_DISTANCE = appConfig.AppSettings.Sensor1To2Distance;
            // 应用功能开关
            isDefect = appConfig.AppSettings.IsDefectDisplay;
            Defectbutton.Text = isDefect ? "缺陷隐藏" : "缺陷显示";

            isKickConfirm = appConfig.AppSettings.IsKickConfirm;
            button6.Text = isKickConfirm ? "关闭踢料确认" : "开启踢料确认";

            isMarginCheck = appConfig.AppSettings.IsMarginCheck;
            button7.Text = isMarginCheck ? "关闭缺料感应" : "开启缺料感应";

            // 新增：应用工单配置文件名到文本框
            textBox2.Text = appConfig.ProductConfigFileName;
            // 加载工单设置
            LoadProductSettings();
        }

        public void SaveMergedConfig()
        {
            try
            {
                // 从界面更新配置对象
                UpdateConfigFromUI();

                // 使用 JsonWriter 来美化输出
                StringBuilder sb = new StringBuilder();
                JsonWriter writer = new JsonWriter(sb);
                writer.PrettyPrint = true;  // 启用美化输出

                JsonMapper.ToJson(appConfig, writer);
                File.WriteAllText(mergedConfigFilePath, sb.ToString());
                AddLog("合并配置文件保存成功");
            }
            catch (Exception ex)
            {
                AddLog($"保存合并配置失败: {ex.Message}");
            }
        }

        private void UpdateConfigFromUI()
        {
            // 更新时间参数
            if (int.TryParse(KickMsTb.Text, out int kickMs))
                appConfig.AppSettings.KickMs = kickMs;
            if (int.TryParse(textBox1.Text, out int passMs))
                appConfig.AppSettings.PassMs = passMs;
            if (int.TryParse(textBox3.Text, out int allowError))
                appConfig.AppSettings.AllowedPositionError = allowError;
            appConfig.AppSettings.Sensor1To2Distance = MaterialTracker.SENSOR1_TO_SENSOR2_DISTANCE;
            // 更新功能开关
            appConfig.AppSettings.IsDefectDisplay = isDefect;
            appConfig.AppSettings.IsKickConfirm = isKickConfirm;
            appConfig.AppSettings.IsMarginCheck = isMarginCheck;

        }
        private void CameraPb_MouseWheel(object sender, MouseEventArgs e)
        {
            PictureBox currentPb = sender as PictureBox;
            if (currentPb == null || currentPb.Image == null) return;

            // 确定当前 PictureBox 的索引
            int pbIndex = -1;
            if (currentPb == cameraPb_01) pbIndex = 0;
            else if (currentPb == cameraPb_02) pbIndex = 1;
            else if (currentPb == cameraPb_03) pbIndex = 2;

            if (pbIndex == -1 ) return;

            int x = e.Location.X;
            int y = e.Location.Y;
            int ow = currentPb.Width;
            int oh = currentPb.Height;
            int VX, VY;  // 因缩放产生的位移矢量

            if (e.Delta > 0) // 放大
            {
                // 第1步
                currentPb.Width += ZoomStep;
                currentPb.Height += ZoomStep;
                // 第2步
                PropertyInfo pInfo = currentPb.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);
                Rectangle rect = (Rectangle)pInfo.GetValue(currentPb, null);
                // 第3步
                currentPb.Width = rect.Width;
                currentPb.Height = rect.Height;
            }
            if (e.Delta < 0) // 缩小
            {
                // 防止一直缩成负值
                if (currentPb.Width < 666)
                    return;

                currentPb.Width -= ZoomStep;
                currentPb.Height -= ZoomStep;
                PropertyInfo pInfo = currentPb.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);
                Rectangle rect = (Rectangle)pInfo.GetValue(currentPb, null);
                currentPb.Width = rect.Width;
                currentPb.Height = rect.Height;
            }

            // 第4步，求因缩放产生的位移，进行补偿，实现锚点缩放的效果
            VX = (int)((double)x * (ow - currentPb.Width) / ow);
            VY = (int)((double)y * (oh - currentPb.Height) / oh);
            currentPb.Location = new System.Drawing.Point(currentPb.Location.X + VX, currentPb.Location.Y + VY);
        }


        private void RestoreOriginalSize(PictureBox pictureBox, int pbIndex)
        {
            if (pictureBox.Image != null)
            {
                pictureBox.Image = pictureBox.Image;
                pictureBox.Size = PicSize[pbIndex];
                pictureBox.Location = PicStartPos[pbIndex];
            }
        }
        private void MacTestForm_FormClosing(object sender, EventArgs e)
        {
            SaveCounts();
            CameraReceiveThread_01.CloseDevice();
            CameraReceiveThread_02.CloseDevice();
            CameraReceiveThread_03.CloseDevice();
            SaveRichTextBoxLog();
            // 释放图像资源
            SafeDisposeImage(cameraPb_01);
            SafeDisposeImage(cameraPb_02);
            SafeDisposeImage(cameraPb_03);
        }

        private void MacTestForm_Closed(object sender, EventArgs e)
        {
            CameraReceiveThread_01.CloseDevice();
            CameraReceiveThread_02.CloseDevice();
            CameraReceiveThread_03.CloseDevice();
            //SaveRichTextBoxLog();
        }
        //运动状态更新
        private void runStateTimer_Tick(object sender, EventArgs e)
        {
            TotalCountTb.Text = SingleItemInfoBuilder.totalCounts.ToString();
            NGCountTb.Text = SingleItemInfoBuilder.NGCounts.ToString();
            OKCountTb.Text = SingleItemInfoBuilder.OKCounts.ToString();

            if (int.Parse(OKCountTb.Text) != 0 && int.Parse(TotalCountTb.Text) != 0)
            {
                double percent = (int.Parse(OKCountTb.Text) * 100.0) / int.Parse(TotalCountTb.Text);
                PercentTb.Text = percent.ToString("F2") + "%"; // 保留2位小数
            }
            else
            {
                PercentTb.Text = "0";
            }
            //PercentTb.Text = (int.Parse(OKCountTb.Text) / c).ToString();

            Camera1OKTb.Text = SingleItemInfoBuilder.Camera1OKCounts.ToString();
            Camera1NGTb.Text = SingleItemInfoBuilder.Camera1NGCounts.ToString();
            Camera1TotalTb.Text = SingleItemInfoBuilder.Camera1TotalCounts.ToString();

            Camera2OKTb.Text = SingleItemInfoBuilder.Camera2OKCounts.ToString();
            Camera2NGTb.Text = SingleItemInfoBuilder.Camera2NGCounts.ToString();
            Camera2TotalTb.Text = SingleItemInfoBuilder.Camera2TotalCounts.ToString();

            Camera3OKTb.Text = SingleItemInfoBuilder.Camera3OKCounts.ToString();
            Camera3NGTb.Text = SingleItemInfoBuilder.Camera3NGCounts.ToString();
            Camera3TotalTb.Text = SingleItemInfoBuilder.Camera3TotalCounts.ToString();

            RateTb.Text = SingleItemInfoBuilder.RateMinutes;
        }
        private void InitializeSaveTimer()
        {
            saveTimer = new System.Windows.Forms.Timer();
            saveTimer.Interval = 3600000; // 每小时保存一次 (3600000ms = 1小时)
            saveTimer.Tick += SaveTimer_Tick;
            saveTimer.Start();

            // 程序启动时立即保存一次
            SaveRichTextBoxLog();
        }
        private void SaveTimer_Tick(object sender, EventArgs e)
        {
            SaveRichTextBoxLog();
        }

        private void SaveRichTextBoxLog()
        {
            try
            {
                // 确保richTextBox1存在
                if (richTextBox1 == null || isClosing)
                    return;

                DateTime currentDate = DateTime.Today;
                string content = richTextBox1.Text;
                int currentLength = content.Length;

                // 确保有内容需要保存
                if (string.IsNullOrWhiteSpace(content))
                    return;

                // 获取日志目录
                string logDirectory = Path.Combine(Application.StartupPath, "Data", "RunData");

                // 确保目录存在
                if (!Directory.Exists(logDirectory))
                    Directory.CreateDirectory(logDirectory);

                // 构建日志文件路径 (每天一个文件)
                string logFilePath = Path.Combine(logDirectory, $"{currentDate:yyyy-MM-dd}.txt");

                // 日期变化或首次保存 - 保存全部内容
                if (currentDate != lastSaveDate || string.IsNullOrEmpty(currentLogFilePath))
                {
                    File.WriteAllText(logFilePath, content);
                    currentLogFilePath = logFilePath;
                    lastSaveDate = currentDate;
                    lastSaveLength = currentLength;
                }
                // 同一天 - 只追加新增内容
                else if (currentLength > lastSaveLength)
                {
                    string newContent = content.Substring(lastSaveLength);
                    File.AppendAllText(logFilePath, newContent);
                    lastSaveLength = currentLength;
                }
            }
            catch (Exception ex)
            {
                // 处理保存错误 (可以记录到另一个地方或显示消息)
                Console.WriteLine($"保存日志失败: {ex.Message}");
            }
        }

        #region 固定轴
        //固定轴运动
        private bool isFixedAxisStart;
        private void FixedAxisMoveBtn_Click(object sender, EventArgs e)
        {
            if (isFixedAxisStart)
            {
                Param_Form.stopAxis(0, appConfig.AxisParameters.Axes[0].DownTime);
                Param_Form.stopAxis(1, appConfig.AxisParameters.Axes[0].DownTime);
                Param_Form.stopAxis(2, appConfig.AxisParameters.Axes[0].DownTime);

                FixedAxisMoveBtn.BackgroundImage = global::InspectionMAC.Properties.Resources.清零拷贝2;
                FixedAxisMoveBtn.Text = "轴运动";
            }
            else
            {
                Param_Form.ContinuousMotion(0, appConfig.AxisParameters.Axes[0].StartSpeed, appConfig.AxisParameters.Axes[0].RunSpeed, appConfig.AxisParameters.Axes[0].UpTime, appConfig.AxisParameters.Axes[0].DownTime, appConfig.AxisParameters.Axes[0].StopSpeed, appConfig.AxisParameters.Axes[0].S_Time, false);
                Param_Form.ContinuousMotion(1, appConfig.AxisParameters.Axes[0].StartSpeed, appConfig.AxisParameters.Axes[0].RunSpeed, appConfig.AxisParameters.Axes[0].UpTime, appConfig.AxisParameters.Axes[0].DownTime, appConfig.AxisParameters.Axes[0].StopSpeed, appConfig.AxisParameters.Axes[0].S_Time, false);
                Param_Form.ContinuousMotion(2, appConfig.AxisParameters.Axes[0].StartSpeed, appConfig.AxisParameters.Axes[0].RunSpeed, appConfig.AxisParameters.Axes[0].UpTime, appConfig.AxisParameters.Axes[0].DownTime, appConfig.AxisParameters.Axes[0].StopSpeed, appConfig.AxisParameters.Axes[0].S_Time, true);

                FixedAxisMoveBtn.BackgroundImage = global::InspectionMAC.Properties.Resources.轴停止拷贝3;
                FixedAxisMoveBtn.Text = "轴停止";
            }
            isFixedAxisStart = !isFixedAxisStart;
        }
        //固定轴停止
        public void FixedAxisStopBtn_Click(object sender, EventArgs e)
        {
            Param_Form.stopAxis(0, appConfig.AxisParameters.Axes[0].DownTime);
            Param_Form.stopAxis(1, appConfig.AxisParameters.Axes[0].DownTime);
            Param_Form.stopAxis(2, appConfig.AxisParameters.Axes[0].DownTime);
        }
        private void ChangeSpeedBtn_Click(object sender, EventArgs e)
        {
            Param_Form.ChangeSpeed(0, "-" + changeSpeedTb.Text, changeTimeTb.Text);
            Param_Form.ChangeSpeed(1, "-" + changeSpeedTb.Text, changeTimeTb.Text);
            Param_Form.ChangeSpeed(2, changeSpeedTb.Text, changeTimeTb.Text);

            appConfig.AxisParameters.Axes[0].RunSpeed = changeSpeedTb.Text;
            appConfig.AxisParameters.Axes[0].UpTime = changeTimeTb.Text;

            SaveMergedConfig();
        }
        //固定轴1清除状态
        private void StateClearBtn01_Click(object sender, EventArgs e)
        {
            Param_Form.StateClean(0);
        }
        //固定轴2清除状态
        private void StateClearBtn02_Click(object sender, EventArgs e)
        {
            Param_Form.StateClean(1);
        }
        //固定轴3清除状态
        private void StateClearBtn03_Click(object sender, EventArgs e)
        {
            Param_Form.StateClean(2);
        }
        #endregion

        #region 入料轴
        //入料轴运动
        private bool isFeedAxisStart;
        private void FeedAxisMoveBtn_Click(object sender, EventArgs e)
        {
            if (isFeedAxisStart)
            {
                Param_Form.stopAxis(3, appConfig.AxisParameters.Axes[1].DownTime);
                FeedAxisMoveBtn.BackgroundImage = global::InspectionMAC.Properties.Resources.清零拷贝2;
                FeedAxisMoveBtn.Text = "轴运动";
            }
            else
            {
                FeedAxisMoveBtn.BackgroundImage = global::InspectionMAC.Properties.Resources.轴停止拷贝3;
                Param_Form.ContinuousMotion(3, appConfig.AxisParameters.Axes[1].StartSpeed, appConfig.AxisParameters.Axes[1].RunSpeed, appConfig.AxisParameters.Axes[1].UpTime, appConfig.AxisParameters.Axes[1].DownTime, appConfig.AxisParameters.Axes[1].StopSpeed, appConfig.AxisParameters.Axes[1].S_Time, true);
                FeedAxisMoveBtn.Text = "轴停止";
            }
            isFeedAxisStart = !isFeedAxisStart;
        }
        //入料轴停止
        public void FeedAxisStopBtn_Click(object sender, EventArgs e)
        {
            Param_Form.stopAxis(3, appConfig.AxisParameters.Axes[1].DownTime);
        }
        //固定轴4清除状态
        private void StateClearBtn04_Click(object sender, EventArgs e)
        {
            Param_Form.StateClean(3);
        }
        //执行速度变换
        private void ChangeSpeedBtn04_Click(object sender, EventArgs e)
        {
            Param_Form.ChangeSpeed(3, changeSpeedTb04.Text, changeTimeTb04.Text);
            appConfig.AxisParameters.Axes[1].RunSpeed = changeSpeedTb04.Text;
            appConfig.AxisParameters.Axes[1].UpTime = changeTimeTb04.Text;
            SaveMergedConfig();
        }

        #endregion

        #region DIO功能
        private void StationDoBtn01_Click(object sender, EventArgs e)
        {
            TestDioThread.iTestDio_Step = 10;
        }

        private void StationDoBtn02_Click(object sender, EventArgs e)
        {
            TestDioThread.iTestDio_Step = 20;
        }

        private void StationDoBtn03_Click(object sender, EventArgs e)
        {
            TestDioThread.iTestDio_Step = 30;
        }

        private void StationDoBtn14_Click(object sender, EventArgs e)
        {
            if (DIO_Thread.Do[14] == 1)
            {
                //StationDoBtn14.Text = "关闭真空帮浦";
                StationDoBtn14.BackgroundImage = global::InspectionMAC.Properties.Resources.清零拷贝2;
                StationDoBtn14.Text = "真空:开";
                DIO_Thread.Do[14] = 0;
            }
            else
            {
                StationDoBtn14.BackgroundImage = global::InspectionMAC.Properties.Resources.轴停止拷贝3;
                StationDoBtn14.Text = "真空:关";
                DIO_Thread.Do[14] = 1;
            }
        }
        #endregion

        #region 相机连续
        public static int cameraContinuousIndex;
        public bool isCameraContinuesOpen = false;
        private void StationContinuousBtn01_Click(object sender, EventArgs e)
        {
            isCameraContinuesOpen = !isCameraContinuesOpen;
            if (isCameraContinuesOpen)
            {
                StartBtn.Enabled = false;
                CameraReceiveThread_01.CloseDevice();
                CameraReceiveThread_02.CloseDevice();
                CameraReceiveThread_03.CloseDevice();

                StationContinuousBtn01.BackgroundImage = global::InspectionMAC.Properties.Resources.轴停止拷贝3;
                StationContinuousBtn01.Text = "停止";
                CameraContinuesThread01.iCameraContinues_Step = 0;
                CameraContinuesThread02.iCameraContinues_Step = 0;
                CameraContinuesThread03.iCameraContinues_Step = 0;

                string appPath = @"D:\MVS\Applications\Win64\MVS.exe";

                try
                {
                    // 检查文件是否存在
                    if (File.Exists(appPath))
                    {
                        // 启动应用程序
                        Process.Start(appPath);
                    }
                    else
                    {
                        MessageBox.Show($"找不到 MVS 程序: {appPath}", "错误",
                                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"打开失败: {ex.Message}", "错误",
                                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                StartBtn.Enabled = true;
                CameraContinuesThread01.iCameraContinues_Step = 2;
                CameraContinuesThread02.iCameraContinues_Step = 2;
                CameraContinuesThread03.iCameraContinues_Step = 2;
                CameraReceiveThread_01.OpenDevice();
                CameraReceiveThread_02.OpenDevice();
                CameraReceiveThread_03.OpenDevice();
                StationContinuousBtn01.BackgroundImage = global::InspectionMAC.Properties.Resources.清零拷贝2;
                StationContinuousBtn01.Text = "连续拍照";

            }
        }

        private void StationContinuousBtn02_Click(object sender, EventArgs e)
        {

        }

        private void StationContinuousBtn03_Click(object sender, EventArgs e)
        {

        }

        private void StationContinuousStopBtn_Click(object sender, EventArgs e)
        {
            CameraContinuesThread01.iCameraContinues_Step = 2;
        }
        private void StationContinuousStopBtn02_Click(object sender, EventArgs e)
        {
            CameraContinuesThread02.iCameraContinues_Step = 2;
        }

        private void StationContinuousStopBtn03_Click(object sender, EventArgs e)
        {
            CameraContinuesThread03.iCameraContinues_Step = 2;
        }
        private void IO_Btn_Click(object sender, EventArgs e)
        {
            if (param_Form2 == null)
            {
                param_Form2 = new Param_Form2();
                param_Form2.Show();
            }
            else
            {
                param_Form2.TopMost = true;

            }
        }


        #endregion


        private void ClearCountBtn_Click(object sender, EventArgs e)
        {
            SingleItemInfoBuilder.ClearCounts();
            
            
        }

        private void AlgorithmBtn_Click(object sender, EventArgs e)
        {
            if (algorithm_Form == null)
            {
                algorithm_Form = new AlgorithmForm();
                algorithm_Form.Show();
            }
            else
            {
                algorithm_Form.TopMost = true;
            }
        }

        private void productSettingBtn_Click(object sender, EventArgs e)
        {
            if (product_Form == null)
            {
                product_Form = new ProductSettingForm();
                product_Form.Show();
            }
            else
            {
                product_Form.TopMost = true;

            }
        }
        public bool isStart = false;
        private bool lastDi0State = false; // 记录DI[1]上一次状态
        private bool lastDi1State = false; // 记录DI[1]上一次状态
        private bool lastDi3State = false; // 记录DI[3]上一次状态

        private void StartBtn_Click(object sender, EventArgs e)
        {
            if (isStart)
            {
                PerformStopOperations();
                //StartBtn.BackgroundImage = global::InspectionMAC.Properties.Resources.启动;
            }
            else
            {
                PerformStartOperations();
                //StartBtn.BackgroundImage = global::InspectionMAC.Properties.Resources.停止;
            }
            isStart = !isStart;
        }

        private void CheckDiSignals()
        {
            // 获取当前DI信号状态（假设DIO_Thread.Di是DI信号数组）
            bool currentDi0 = DIO_Thread.Di[0] == 1;
            bool currentDi1 = DIO_Thread.Di[1] == 1;
            bool currentDi3 = DIO_Thread.Di[3] == 1;

            // DI[1]上升沿检测：信号从0变为1
            if (currentDi1 && !lastDi1State)
            {
                if (!isStart)
                {
                    PerformStartOperations();
                    //StartBtn.Text = "停止";
                    isStart = true;
                    AddLog("DI[1]信号触发系统启动");
                }
            }

            // DI[3]上升沿检测：信号从0变为1
            if ((currentDi3 && !lastDi3State) || (currentDi0 && !lastDi0State))
            {
                if (isStart)
                {
                    PerformStopOperations();
                    //StartBtn.Text = "启动";
                    isStart = false;
                    AddLog("DI[3]信号触发系统停止");
                }
            }

            // 更新信号历史状态
            lastDi0State = currentDi0;
            lastDi1State = currentDi1;
            lastDi3State = currentDi3;
        }

        private void PerformStartOperations()
        {
            StartBtn.BackgroundImage = global::InspectionMAC.Properties.Resources.停止;
            StationContinuousBtn01.Enabled = false;

            StationDoBtn01.Enabled = false;
            StationDoBtn02.Enabled = false;
            StationDoBtn03.Enabled = false;

            StationDoBtn14.Enabled = false;
            FixedAxisMoveBtn.Enabled = false;
            FeedAxisMoveBtn.Enabled = false;
            FixedAxisStopBtn.Enabled = false;
            FeedAxisStopBtn.Enabled = false;
            ClearCountBtn.Enabled = false;
            panel1.Enabled = false;
            if (!isHaveCard)
                return;
            Param_Form.ContinuousMotion(0,appConfig.AxisParameters.Axes[0].StartSpeed, appConfig.AxisParameters.Axes[0].RunSpeed, appConfig.AxisParameters.Axes[0].UpTime, appConfig.AxisParameters.Axes[0].DownTime, appConfig.AxisParameters.Axes[0].StopSpeed, appConfig.AxisParameters.Axes[0].S_Time, false);
            Param_Form.ContinuousMotion(1, appConfig.AxisParameters.Axes[0].StartSpeed, appConfig.AxisParameters.Axes[0].RunSpeed, appConfig.AxisParameters.Axes[0].UpTime, appConfig.AxisParameters.Axes[0].DownTime, appConfig.AxisParameters.Axes[0].StopSpeed, appConfig.AxisParameters.Axes[0].S_Time, false);
            Param_Form.ContinuousMotion(2, appConfig.AxisParameters.Axes[0].StartSpeed, appConfig.AxisParameters.Axes[0].RunSpeed, appConfig.AxisParameters.Axes[0].UpTime, appConfig.AxisParameters.Axes[0].DownTime, appConfig.AxisParameters.Axes[0].StopSpeed, appConfig.AxisParameters.Axes[0].S_Time, true);
            Param_Form.ContinuousMotion(3, appConfig.AxisParameters.Axes[1].StartSpeed, appConfig.AxisParameters.Axes[1].RunSpeed, appConfig.AxisParameters.Axes[1].UpTime, appConfig.AxisParameters.Axes[1].DownTime, appConfig.AxisParameters.Axes[1].StopSpeed, appConfig.AxisParameters.Axes[1].S_Time, true);
            DIO_Thread.Do[14] = 1;
            DIO_Thread.Do[6] = 1;
            DIO_Thread.Do[7] = 0;
            

        }

        private void PerformStopOperations()
        {
            StartBtn.BackgroundImage = global::InspectionMAC.Properties.Resources.启动;
            StationContinuousBtn01.Enabled = true;

            StationDoBtn01.Enabled = true;
            StationDoBtn02.Enabled = true;
            StationDoBtn03.Enabled = true;

            StationDoBtn14.Enabled = true;
            FixedAxisMoveBtn.Enabled = true;
            FeedAxisMoveBtn.Enabled = true;
            FixedAxisStopBtn.Enabled = true;
            FeedAxisStopBtn.Enabled = true;
            ClearCountBtn.Enabled = true;

            panel1.Enabled = true;
            if (!isHaveCard)
                return;
            DIO_Thread.Do[14] = 0;
            DIO_Thread.Do[6] = 0;
            DIO_Thread.Do[7] = 1;
            FixedAxisStopBtn_Click(null, EventArgs.Empty);
            FeedAxisStopBtn_Click(null, EventArgs.Empty);
        }

        public static ConcurrentQueue<Bitmap> DisplayQueue01 = new ConcurrentQueue<Bitmap>();
        public static ConcurrentQueue<Bitmap> DisplayQueue02 = new ConcurrentQueue<Bitmap>();
        public static ConcurrentQueue<Bitmap> DisplayQueue03 = new ConcurrentQueue<Bitmap>();

        private System.Windows.Forms.Timer displayUpdateTimer;

        private void DisplayUpdateTimer_Tick(object sender, EventArgs e)
        {
            UpdateDisplay(sender, e); // 更新图像显示
            CheckDiSignals();         // 检查DI信号状态
        }
        private void InitializeDisplayTimer()
        {
            displayUpdateTimer = new System.Windows.Forms.Timer();
            displayUpdateTimer.Interval = 100; // 100毫秒更新一次
            displayUpdateTimer.Tick += DisplayUpdateTimer_Tick;
            displayUpdateTimer.Start();
        }

        private void UpdateDisplay(object sender, EventArgs e)
        {
            // 更新工位1
            if (DisplayQueue01.TryDequeue(out Bitmap bmp1))
            {
                lastQueueUpdateTime = DateTime.Now; // 重置时间
                UpdatePictureBox(cameraPb_01, bmp1,1);
            }

            // 更新工位2
            if (DisplayQueue02.TryDequeue(out Bitmap bmp2))
            {
                lastQueueUpdateTime = DateTime.Now; // 重置时间
                UpdatePictureBox(cameraPb_02, bmp2,2);
            }

            // 更新工位3
            if (DisplayQueue03.TryDequeue(out Bitmap bmp3))
            {
                lastQueueUpdateTime = DateTime.Now; // 重置时间
                UpdatePictureBox(cameraPb_03, bmp3,3);
            }
        }

        private void UpdatePictureBox(PictureBox pictureBox, Bitmap newImage, int index)
        {
            if (pictureBox.InvokeRequired)
            {
                pictureBox.Invoke(new Action<PictureBox, Bitmap, int>(UpdatePictureBox), pictureBox, newImage, index);
                return;
            }

            // 释放旧图像
            //if (pictureBox.Image != null)
            //{
            //    var oldImage = pictureBox.Image;
            //    pictureBox.Image = null;
            //    oldImage.Dispose();
            //}

            pictureBox.Image = newImage;
            if (index == 1)
            {
                RestoreOriginalSize(cameraPb_01, 0);
            }
            if (index == 2)
            {
                RestoreOriginalSize(cameraPb_02, 1);
            }
            if (index == 3)
            {
                RestoreOriginalSize(cameraPb_03, 2);
            }

        }


        private void cameraPb_02_Click(object sender, EventArgs e)
        {

        }
        public void AddLog(string message)
        {
            if (richTextBox1.InvokeRequired)
            {
                richTextBox1.Invoke(new Action<string>(AddLog), new object[] { message });
                return;
            }

            string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            richTextBox1.AppendText($"{timestamp} - {message}\n");
            richTextBox1.ScrollToCaret(); // 自动滚动到最新内容
        }

        // 添加产品设置相关字段
        private string productName = "";
        private HashSet<DefectType> selectedDefectTypes = new HashSet<DefectType>();

        public static string SettingsFilePath = "ProductSettings.json";

        // 配置键常量
        public static class ConfigKeys
        {
            public const string ProductName = "ProductName";
            public const string ProductType = "ProductType";
            public const string CameraSettings = "CameraSettings";
            public const string SelectedDefectTypes_Capsule = "SelectedDefectTypes_Capsule";
            public const string SelectedDefectTypes_Tablet = "SelectedDefectTypes_Tablet";
            public const string TaskGroup1 = "TaskGroup1";
            public const string TaskGroup2 = "TaskGroup2";
            public const string TaskGroup3 = "TaskGroup3";
        }

        private readonly Dictionary<DefectType, string> defectTypeNames = new Dictionary<DefectType, string>
        {
            { DefectType.空泡, "空泡" },
            { DefectType.折痕, "折痕" },
            { DefectType.破边, "破边" },
            { DefectType.批次不良, "批次不良" },
            { DefectType.压泡, "压泡" },
            { DefectType.脏污, "脏污" },
            { DefectType.铝箔不良, "铝箔不良" },
            { DefectType.脱帽, "脱帽" },
            { DefectType.混料, "混料" },
            { DefectType.头发, "头发" },
            { DefectType.漏粉, "漏粉" },
            { DefectType.多粒, "多粒" },
            { DefectType.压痕, "压痕" },
            { DefectType.网纹不良, "网纹不良" },
            { DefectType.劈叉, "劈叉" },
            { DefectType.钢印OK, "钢印OK" },
            { DefectType.钢印NG, "钢印NG" }
        };

        private readonly Dictionary<DefectType1, string> defectTypeNamesTablet = new Dictionary<DefectType1, string>
        {
            { DefectType1.空泡, "空泡" },
            { DefectType1.折痕, "折痕" },
            { DefectType1.破边, "破边" },
            { DefectType1.批次不良, "批次不良" },
            { DefectType1.压泡, "压泡" },
            { DefectType1.脏污, "脏污" },
            { DefectType1.铝箔不良, "铝箔不良" },
            { DefectType1.裂纹, "裂纹" },
            { DefectType1.混料, "混料" },
            { DefectType1.头发, "头发" },
            { DefectType1.漏粉, "漏粉" },
            { DefectType1.多粒, "多粒" },
            { DefectType1.崩缺, "崩缺" },
            { DefectType1.网纹不良, "网纹不良" },
            { DefectType1.钢印OK, "钢印OK" },
            { DefectType1.钢印NG, "钢印NG" }
        };

        private uint userIndex;
        // 修改LoadProductSettings方法
        private void LoadProductSettings()
        {
            try
            {
                // 使用app_config.json中配置的文件名
                string configFileName = appConfig.ProductConfigFileName;
                SettingsFilePath = appConfig.ProductConfigFileName;
                string configFilePath = Path.Combine(Application.StartupPath, configFileName);

                AddLog($"开始加载工单配置: {configFilePath}");

                if (File.Exists(configFilePath))
                {
                    string json = File.ReadAllText(configFilePath);
                    JsonData settings = JsonMapper.ToObject(json);

                    // 获取产品名称和类型
                    productName = settings["ProductName"]?.ToString() ?? "";
                    AddLog($"产品名称: {productName}");

                    // 默认行为：从文件读取计数
                    if (settings.Keys.Contains("NGCounts"))
                    {
                        SingleItemInfoBuilder.NGCounts = (int)settings["NGCounts"];
                    }
                    else
                    {
                        SingleItemInfoBuilder.NGCounts = 0;
                    }

                    if (settings.Keys.Contains("OKCounts"))
                    {
                        SingleItemInfoBuilder.OKCounts = (int)settings["OKCounts"];
                    }
                    else
                    {
                        SingleItemInfoBuilder.OKCounts = 0;
                    }

                    if (settings.Keys.Contains("totalCounts"))
                    {
                        SingleItemInfoBuilder.totalCounts = (int)settings["totalCounts"];
                    }
                    else
                    {
                        SingleItemInfoBuilder.totalCounts = 0;
                    }

                    AddLog($"加载计数: NG={SingleItemInfoBuilder.NGCounts}, OK={SingleItemInfoBuilder.OKCounts}, Total={SingleItemInfoBuilder.totalCounts}");


                    if (settings.Keys.Contains("ProductType"))
                    {
                        int productType = int.Parse(settings["ProductType"].ToString());
                        AlgorithmModule.CurrentProductType = (ProductType)productType;
                        AlgorithmModule.CurrentEngine = productType == 0 ? "20251027_jbj_caps.engine" : "20251027_jbj_tab.engine";
                        AddLog($"选择引擎为: {AlgorithmModule.CurrentEngine}, 产品类型: {AlgorithmModule.CurrentProductType}");
                    }
                    // 根据产品类型加载对应的缺陷类型设置
                    LoadDefectTypesByProductType(settings);

                    AddLog($"已加载产品设置: {productName}, 类型: {AlgorithmModule.CurrentProductType}, 文件: {configFileName}");
                    // 获取相机设置
                    if (settings.Keys.Contains("CameraSettings"))
                    {
                        int cameraSetting = int.Parse(settings["CameraSettings"].ToString());
                        userIndex = (uint)cameraSetting;
                        AddLog($"相机用户设置: {userIndex}");

                        // 应用相机设置
                        if (!isHaveCard)
                            return;
                        CameraReceiveThread_01.SwitchUserSet(userIndex);
                        CameraReceiveThread_02.SwitchUserSet(userIndex);
                        CameraReceiveThread_03.SwitchUserSet(userIndex);
                    }

                    
                }
                else
                {
                    AddLog($"工单配置文件不存在: {configFilePath}");
                    SetDefaultProductSettings();
                    // 新文件计数归零
                    SingleItemInfoBuilder.NGCounts = 0;
                    SingleItemInfoBuilder.OKCounts = 0;
                    SingleItemInfoBuilder.totalCounts = 0;
                }
            }
            catch (Exception ex)
            {
                AddLog($"加载产品设置时出错: {ex.Message}");
                SetDefaultProductSettings();
            }
        }
        private void ReloadProductSettings()
        {
            try
            {
                // 使用app_config.json中配置的文件名
                string configFileName = appConfig.ProductConfigFileName;
                SettingsFilePath = appConfig.ProductConfigFileName;
                string configFilePath = Path.Combine(Application.StartupPath, configFileName);

                AddLog($"开始加载工单配置: {configFilePath}");

                if (File.Exists(configFilePath))
                {
                    string json = File.ReadAllText(configFilePath);
                    JsonData settings = JsonMapper.ToObject(json);

                    // 获取产品名称和类型
                    productName = settings["ProductName"]?.ToString() ?? "";
                    AddLog($"产品名称: {productName}");

                    SingleItemInfoBuilder.NGCounts = 0;
                    SingleItemInfoBuilder.OKCounts = 0;
                    SingleItemInfoBuilder.totalCounts = 0;
                    settings["NGCounts"] = SingleItemInfoBuilder.NGCounts;
                    settings["OKCounts"] = SingleItemInfoBuilder.OKCounts;
                    settings["totalCounts"] = SingleItemInfoBuilder.totalCounts;

                    File.WriteAllText(SettingsFilePath, settings.ToJson());
                    AddLog($"加载计数: NG={SingleItemInfoBuilder.NGCounts}, OK={SingleItemInfoBuilder.OKCounts}, Total={SingleItemInfoBuilder.totalCounts}");


                    if (settings.Keys.Contains("ProductType"))
                    {
                        int productType = int.Parse(settings["ProductType"].ToString());
                        AlgorithmModule.CurrentProductType = (ProductType)productType;
                        AlgorithmModule.CurrentEngine = productType == 0 ? "20251027_jbj_caps.engine" : "20251027_jbj_tab.engine";
                        AddLog($"选择引擎为: {AlgorithmModule.CurrentEngine}, 产品类型: {AlgorithmModule.CurrentProductType}");
                    }
                    // 根据产品类型加载对应的缺陷类型设置
                    LoadDefectTypesByProductType(settings);

                    AddLog($"已加载产品设置: {productName}, 类型: {AlgorithmModule.CurrentProductType}, 文件: {configFileName}");
                    // 获取相机设置
                    if (settings.Keys.Contains("CameraSettings"))
                    {
                        int cameraSetting = int.Parse(settings["CameraSettings"].ToString());
                        userIndex = (uint)cameraSetting;
                        AddLog($"相机用户设置: {userIndex}");

                        // 应用相机设置
                        if (!isHaveCard)
                            return;
                        CameraReceiveThread_01.SwitchUserSet(userIndex);
                        CameraReceiveThread_02.SwitchUserSet(userIndex);
                        CameraReceiveThread_03.SwitchUserSet(userIndex);
                    }


                }
                else
                {
                    AddLog($"工单配置文件不存在: {configFilePath}");
                    SetDefaultProductSettings();
                    // 新文件计数归零
                    SingleItemInfoBuilder.NGCounts = 0;
                    SingleItemInfoBuilder.OKCounts = 0;
                    SingleItemInfoBuilder.totalCounts = 0;
                }
            }
            catch (Exception ex)
            {
                AddLog($"加载产品设置时出错: {ex.Message}");
                SetDefaultProductSettings();
            }
        }
        private void SaveCounts()
        {
            try
            {
                // 使用app_config.json中配置的文件名
                string configFileName = appConfig.ProductConfigFileName;
                SettingsFilePath = appConfig.ProductConfigFileName;
                string configFilePath = Path.Combine(Application.StartupPath, configFileName);


                if (File.Exists(configFilePath))
                {
                    string json = File.ReadAllText(configFilePath);
                    JsonData settings = JsonMapper.ToObject(json);


                    settings["NGCounts"] = SingleItemInfoBuilder.NGCounts;
                    settings["OKCounts"] = SingleItemInfoBuilder.OKCounts;
                    settings["totalCounts"] = SingleItemInfoBuilder.totalCounts;

                    File.WriteAllText(SettingsFilePath, settings.ToJson());

                }
            }
            catch (Exception ex)
            {

            }
        }
        // 修改后的缺陷类型加载方法
        private void LoadDefectTypesByProductType(JsonData settings)
        {
            try
            {
                // 清空现有的缺陷类型设置
                AlgorithmModule.SelectedDefectTypes.Clear();
                AlgorithmModule.SelectedDefectTypesTablet.Clear();

                AddLog($"开始加载缺陷类型，当前产品类型: {AlgorithmModule.CurrentProductType}");

                // 根据当前产品类型加载对应的缺陷类型
                if (AlgorithmModule.CurrentProductType == ProductType.Capsule)
                {
                    // 加载胶囊缺陷类型
                    if (settings.Keys.Contains("SelectedDefectTypes_Capsule"))
                    {
                        JsonData selectedTypes = settings["SelectedDefectTypes_Capsule"];
                        AddLog($"找到胶囊缺陷类型配置，数量: {selectedTypes.Count}");

                        var reverseMapping = defectTypeNames.ToDictionary(pair => pair.Value, pair => pair.Key);

                        int loadedCount = 0;
                        foreach (JsonData typeName in selectedTypes)
                        {
                            string name = typeName.ToString();
                            if (reverseMapping.TryGetValue(name, out DefectType defectType))
                            {
                                AlgorithmModule.SelectedDefectTypes.Add((int)defectType);
                                loadedCount++;
                                AddLog($"加载胶囊缺陷类型: {name} -> {defectType}");
                            }
                            else
                            {
                                AddLog($"警告: 未知的胶囊缺陷类型: {name}");
                            }
                        }
                        AddLog($"已加载胶囊缺陷类型: {loadedCount} 种");
                    }
                    else
                    {
                        AddLog("警告: 工单配置中未找到胶囊缺陷类型设置");
                        SetDefaultCapsuleDefectTypes();
                    }
                }
                else // ProductType.Tablet
                {
                    // 加载片剂缺陷类型
                    if (settings.Keys.Contains("SelectedDefectTypes_Tablet"))
                    {
                        JsonData selectedTypes = settings["SelectedDefectTypes_Tablet"];
                        AddLog($"找到片剂缺陷类型配置，数量: {selectedTypes.Count}");

                        var reverseMappingTablet = defectTypeNamesTablet.ToDictionary(pair => pair.Value, pair => pair.Key);

                        int loadedCount = 0;
                        foreach (JsonData typeName in selectedTypes)
                        {
                            string name = typeName.ToString();
                            if (reverseMappingTablet.TryGetValue(name, out DefectType1 defectType))
                            {
                                AlgorithmModule.SelectedDefectTypesTablet.Add((int)defectType);
                                loadedCount++;
                                AddLog($"加载片剂缺陷类型: {name} -> {defectType}");
                            }
                            else
                            {
                                AddLog($"警告: 未知的片剂缺陷类型: {name}");
                            }
                        }
                        AddLog($"已加载片剂缺陷类型: {loadedCount} 种");
                    }
                    else
                    {
                        AddLog("警告: 工单配置中未找到片剂缺陷类型设置");
                        SetDefaultTabletDefectTypes();
                    }
                }
            }
            catch (Exception ex)
            {
                AddLog($"加载缺陷类型时出错: {ex.Message}");
                // 出错时设置默认缺陷类型
                if (AlgorithmModule.CurrentProductType == ProductType.Capsule)
                {
                    SetDefaultCapsuleDefectTypes();
                }
                else
                {
                    SetDefaultTabletDefectTypes();
                }
            }
        }

        // 新增默认缺陷类型设置方法
        private void SetDefaultCapsuleDefectTypes()
        {
            AlgorithmModule.SelectedDefectTypes = new HashSet<int>(
                Enum.GetValues(typeof(DefectType))
                    .Cast<DefectType>()
                    .Where(dt => dt != DefectType.None && dt != DefectType.未找到该缺陷类型)
                    .Select(dt => (int)dt)
            );
            AddLog($"使用默认胶囊缺陷类型: {AlgorithmModule.SelectedDefectTypes.Count} 种");
        }

        private void SetDefaultTabletDefectTypes()
        {
            AlgorithmModule.SelectedDefectTypesTablet = new HashSet<int>(
                Enum.GetValues(typeof(DefectType1))
                    .Cast<DefectType1>()
                    .Where(dt => dt != DefectType1.None && dt != DefectType1.未找到该缺陷类型)
                    .Select(dt => (int)dt)
            );
            AddLog($"使用默认片剂缺陷类型: {AlgorithmModule.SelectedDefectTypesTablet.Count} 种");
        }
        // 设置默认产品设置
        private void SetDefaultProductSettings()
        {
            productName = "DefaultProduct";
            AlgorithmModule.CurrentProductType = ProductType.Capsule;
            AlgorithmModule.CurrentEngine = "20251027_jbj_caps.engine";
            userIndex = 1;

            AddLog("使用默认产品设置");

            // 设置默认缺陷类型
            if (AlgorithmModule.CurrentProductType == ProductType.Capsule)
            {
                SetDefaultCapsuleDefectTypes();
            }
            else
            {
                SetDefaultTabletDefectTypes();
            }
        }


        private System.Windows.Forms.Timer idleDetectionTimer;
        private DateTime lastQueueUpdateTime = DateTime.Now;

        private void InitializeIdleDetectionTimer()
        {
            idleDetectionTimer = new System.Windows.Forms.Timer();
            idleDetectionTimer.Interval = 1000; // 每秒检查一次
            idleDetectionTimer.Tick += CheckQueueIdleTime;
            idleDetectionTimer.Start();
        }
        private void CheckQueueIdleTime(object sender, EventArgs e)
        {
            // 检查是否超过10秒没有队列更新
            if ((DateTime.Now - lastQueueUpdateTime).TotalSeconds > 10)
            {
                AlgorithmThread.iAlgorithm_Step = 10;
            }
            // 如果有队列更新且算法线程正在运行，则停止算法线程
            else if ((DateTime.Now - lastQueueUpdateTime).TotalSeconds <= 20)
            {
                AlgorithmThread.iAlgorithm_Step = 45;
            }
        }

        private void panel3_Paint(object sender, PaintEventArgs e)
        {

        }

        private void panel7_Paint(object sender, PaintEventArgs e)
        {

        }

        public bool isDefect = false;
        private void Defectbutton_Click(object sender, EventArgs e)
        {

            if (isDefect)
            {
                Defectbutton.Text = "缺陷显示";
                Defectbutton.BackgroundImage = global::InspectionMAC.Properties.Resources.hui;
            }
            else
            {
                Defectbutton.Text = "缺陷隐藏";
                Defectbutton.BackgroundImage = global::InspectionMAC.Properties.Resources.lv_拷贝1;
            }
            isDefect = !isDefect;
            SaveMergedConfig();
        }

        private void btnShutdown_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("确定要关闭计算机吗？", "关机确认",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                Process.Start("shutdown", "/s /t 0");
            }
        }

        private void btnRestart_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("确定要重启计算机吗？", "重启确认",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                Process.Start("shutdown", "/r /t 0");
            }
        }

        public bool isForceKick = false;
        private void isNGButton_Click(object sender, EventArgs e)
        {
            if (isForceKick)
            {
                isNGButton.Text = "开启强制踢料";
                isNGButton.BackgroundImage = global::InspectionMAC.Properties.Resources.hui;
            }
            else
            {
                isNGButton.Text = "关闭强制踢料";
                isNGButton.BackgroundImage = global::InspectionMAC.Properties.Resources.lv_拷贝1;
            }
            isForceKick = !isForceKick;
        }

        public int Kick_ms = 100;
        public int Pass_ms = 100;
        private void BtnSet_Click(object sender, EventArgs e)
        {
            if (int.TryParse(KickMsTb.Text, out int newValue))
            {
                Kick_ms = newValue;
            }
            else
            {
                MessageBox.Show("请输入有效的整数！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            if (int.TryParse(textBox1.Text, out int newValue1))
            {
                Pass_ms = newValue1;
                AddPointThread01.MIN_TRIGGER_INTERVAL_MS = Pass_ms;
                AddPointThread02.MIN_TRIGGER_INTERVAL_MS = Pass_ms;
                NGKickManager.MIN_KICK_INTERVAL_MS = Pass_ms;
            }
            else
            {
                MessageBox.Show("请输入有效的整数！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            if (int.TryParse(textBox3.Text, out int newValue2))
            {
                MaterialTracker.ALLOWED_POSITION_ERROR = newValue2;
            }
            else
            {
                MessageBox.Show("请输入有效的整数！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            // 保存合并配置
            SaveMergedConfig();
            panel2.BringToFront();
            isonPanel = !isonPanel;
        }

        public bool isKickConfirm;
        private void button6_Click(object sender, EventArgs e)
        {
            if (isKickConfirm)
            {
                button6.Text = "开启踢料确认";
                button6.BackgroundImage = global::InspectionMAC.Properties.Resources.hui;
            }
            else
            {
                button6.Text = "关闭踢料确认";
                button6.BackgroundImage = global::InspectionMAC.Properties.Resources.lv_拷贝1;
            }
            isKickConfirm = !isKickConfirm;
            SaveMergedConfig();
        }

        public bool isMarginCheck;
        private void button7_Click(object sender, EventArgs e)
        {
            if (isMarginCheck)
            {
                button7.BackgroundImage = global::InspectionMAC.Properties.Resources.hui;
                button7.Text = "开启缺料感应";
                MarginThread.StopRecordLocationThread();
               
            }
            else
            {
                button7.BackgroundImage = global::InspectionMAC.Properties.Resources.lv_拷贝1;
                button7.Text = "关闭缺料感应";
                MarginThread.RecordLocation_Thread();
                
            }
            isMarginCheck = !isMarginCheck;
            SaveMergedConfig();
        }

        public bool isPointSet;
        private void PointSetBtn_Click(object sender, EventArgs e)
        {
            LTDMC.dmc_compare_clear_points(0, 0);
            LTDMC.dmc_compare_clear_points(0, 1);
            LTDMC.dmc_compare_clear_points(0, 2);
            AddPointThread01.iAddPoint_Step = 0;
            AddPointThread02.iAddPoint_Step = 0;
            isPointSet = true;
            if (pointset_Form == null)
            {
                pointset_Form = new PointSetForm();
                pointset_Form.Show();
            }
            else
            {
                pointset_Form.TopMost = true;
            }
        }

        public void ShowAlarmForm(string str)
        {
            if (alarm_Form == null)
            {
                alarm_Form = new AlarmForm();
                // 先更新文字再显示
                alarm_Form.UpdateAlarmString(str);
                alarm_Form.Show();
                // 设置窗体属性确保可点击
                alarm_Form.TopMost = true;
                alarm_Form.Focus();
                alarm_Form.BringToFront();
            }
            else
            {
                // 窗体已存在时也要更新文字
                alarm_Form.UpdateAlarmString(str);
                alarm_Form.TopMost = true;
                alarm_Form.Focus();
                alarm_Form.BringToFront();
                alarm_Form.WindowState = FormWindowState.Normal; // 确保不是最小化状态
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            changeSpeedTb.Text = (int.Parse(changeSpeedTb.Text) + 1000).ToString();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            changeSpeedTb.Text = (int.Parse(changeSpeedTb.Text) - 1000).ToString();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            changeSpeedTb04.Text = (int.Parse(changeSpeedTb04.Text) + 1000).ToString();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            changeSpeedTb04.Text = (int.Parse(changeSpeedTb04.Text) - 1000).ToString();
        }


        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                using (OpenFileDialog openFileDialog = new OpenFileDialog())
                {
                    openFileDialog.InitialDirectory = Application.StartupPath;
                    openFileDialog.Filter = "JSON文件 (*.json)|*.json|所有文件 (*.*)|*.*";
                    openFileDialog.FilterIndex = 1;
                    openFileDialog.RestoreDirectory = true;
                    openFileDialog.Title = "选择工单配置文件";

                    if (openFileDialog.ShowDialog() == DialogResult.OK)
                    {
                        string selectedFileName = Path.GetFileName(openFileDialog.FileName);

                        // 验证文件格式是否正确
                        if (ValidateProductConfigFile(openFileDialog.FileName))
                        {
                            // 切换工单时计数归零
                            SingleItemInfoBuilder.NGCounts = 0;
                            SingleItemInfoBuilder.OKCounts = 0;
                            SingleItemInfoBuilder.totalCounts = 0;

                            // 更新配置
                            appConfig.ProductConfigFileName = selectedFileName;

                            // 更新文本框显示
                            textBox2.Text = selectedFileName;

                            // 保存到app_config.json
                            SaveMergedConfig();

                            // 重新加载工单设置
                            ReloadProductSettings();

                            AddLog($"已切换工单配置文件: {selectedFileName}, 计数已归零");
                        }
                        else
                        {
                            MessageBox.Show("选择的文件格式不正确，请选择有效的工单配置文件。",
                                            "文件格式错误",
                                            MessageBoxButtons.OK,
                                            MessageBoxIcon.Error);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                AddLog($"选择工单配置文件时出错: {ex.Message}");
                MessageBox.Show($"加载配置文件失败: {ex.Message}", "错误",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public void ReloadProduct(string selectedFileName)
        {
            appConfig.ProductConfigFileName = selectedFileName;

            // 更新文本框显示
            textBox2.Text = selectedFileName;

            // 保存到app_config.json
            SaveMergedConfig();

            // 重新加载工单设置
            ReloadProductSettings();
        }
        // 验证工单配置文件格式
        private bool ValidateProductConfigFile(string filePath)
        {
            try
            {
                if (!File.Exists(filePath))
                    return false;

                string json = File.ReadAllText(filePath);
                JsonData settings = JsonMapper.ToObject(json);

                // 检查必要的字段
                return settings.Keys.Contains("ProductName") &&
                       settings.Keys.Contains("ProductType") &&
                       settings.Keys.Contains("CameraSettings");
            }
            catch
            {
                return false;
            }
        }


        private void SafeDisposeImage(PictureBox pictureBox)
        {
            if (pictureBox.InvokeRequired)
            {
                pictureBox.Invoke(new Action<PictureBox>(SafeDisposeImage), pictureBox);
                return;
            }

            if (pictureBox.Image != null)
            {
                var image = pictureBox.Image;
                pictureBox.Image = null;
                image.Dispose();
            }
        }

        // 新增的合并配置类
        public class AppConfig
        {
            public AxisParameters AxisParameters { get; set; } = new AxisParameters();
            public AppSettings AppSettings { get; set; } = new AppSettings();

            public string ProductConfigFileName { get; set; }
        }

        public class AppSettings
        {
            // 相机配置
            public CameraConfig[] Cameras { get; set; } = new CameraConfig[3];

            // 时间参数
            public int KickMs { get; set; } = 100;
            public int PassMs { get; set; } = 100;

            // 功能开关
            public bool IsDefectDisplay { get; set; } = false;
            public bool IsKickConfirm { get; set; } = false;
            public bool IsMarginCheck { get; set; } = false;

            //掉料检测相关
            public uint Sensor1To2Distance { get; set; } = 144726;
            public int AllowedPositionError { get; set; } = 5000;
        }

        // 现有的轴参数类保持不变
        public class AxisParameters
        {
            public List<AxisConfig> Axes { get; set; } = new List<AxisConfig>();
        }

        public class AxisConfig
        {
            public string StartSpeed { get; set; }
            public string RunSpeed { get; set; }
            public string UpTime { get; set; }
            public string DownTime { get; set; }
            public string StopSpeed { get; set; }
            public string S_Time { get; set; }
            public string MotorCircle { get; set; }
            public bool IsForward { get; set; }
            public string ChangeSpeed { get; set; }
            public string ChangeTime { get; set; }
        }

        public class CameraConfig
        {
            public string CameraId { get; set; } = "";
        }

        private bool isonPanel;

        private void button8_MouseClick(object sender, MouseEventArgs e)
        {
            if (isonPanel)
            {
                panel2.SendToBack();
            }
            else
            {
                panel2.BringToFront();
            }
            isonPanel = !isonPanel;
        }
    }
}
